
#include "settings.h"
#include "mlog.h"
#include <string.h>

#define COAP_SERVER_IP
#define COAP_SERVER_PORT

enum{
	DEVICE_WATER_METER = 1,
	DEVICE_SINGLE_PHASE_ELECTRIC_METER = 2,
	DEVICE_SMART_LOCK = 3,
	DEVICE_FLOWMETER = 4,
	DEVICE_THREE_PHASE_ELECTRIC_METER = 5,
	DEVICE_LINE_FIRE_ALARM = 6,
	DEVICE_WATER_VALVE = 7,
	DEVICE_DTU = 8,
};

#define SLAVE_DEVICE_TYPE DEVICE_DTU


//esp_partition_t *sys_settings_partition = NULL;
/*参数结构体*/
SystemSettings SystemSetting[SETTINGS_MAX_NUM] = {0};
char* SystemSettingName[SETTINGS_MAX_NUM] = {0};
/*实际存储参数的地方*/
uint8_t SystemSettingsBuf[SETTINGS_BUF_SIZE] = {0};

void System_SettingsInitDefault(void)
{
	
	memset(SystemSetting, 0, sizeof(SystemSettings) * SETTINGS_MAX_NUM);
	
	SystemSettingName[SETTINGS_SIGN_STRING                  ] = "SETTINGS_SIGN_STRING------>:"; SystemSetting[SETTINGS_SIGN_STRING 				].nodePtr = (uint8_t*)"Author by Cc";				    //效验字符串
    SystemSettingName[SETTINGS_SOFT_VERSION                 ] = "SETTINGS_SOFT_VERSION----->:"; SystemSetting[SETTINGS_SOFT_VERSION				].nodePtr = (uint8_t*)"1.0.0.0";                	    //软件版本
	SystemSettingName[SETTINGS_DEVICE_SN                    ] = "SETTINGS_DEVICE_SN-------->:"; SystemSetting[SETTINGS_DEVICE_SN       			].nodePtr = (uint8_t*)"NB0000000001";           	    //采集器序列号
	SystemSettingName[SETTINGS_DEVICE_TYPE                  ] = "SETTINGS_DEVICE_TYPE------>:"; SystemSetting[SETTINGS_DEVICE_TYPE     			].nodePtr = (uint8_t*)"01";                     	    //设备类型
	SystemSettingName[SETTINGS_HARDWARE_VERSION             ] = "SETTINGS_HARDWARE_VERSION->:"; SystemSetting[SETTINGS_HARDWARE_VERSION         ].nodePtr = (uint8_t*)"1.0";                     	    //硬件版本
	SystemSettingName[SETTINGS_SYS_DATETIME                 ] = "SETTINGS_SYS_DATETIME----->:"; SystemSetting[SETTINGS_SYS_DATETIME    			].nodePtr = (uint8_t*)"2021-04-04 19:58:22";    	    //系统时间
	SystemSettingName[SETTINGS_UART_CONFIG                  ] = "SETTINGS_UART_CONFIG------>:"; SystemSetting[SETTINGS_UART_CONFIG    			].nodePtr = (uint8_t*)"115200,1,0";             	    //串口1通讯波特率，默认115200,停止位 1:0个  2:1.5个 3:2个，效验0:无 1：奇效验 2：偶效验
	SystemSettingName[SETTINGS_AUTO_REBOOT_TIME	            ] = "SETTINGS_AUTO_REBOOT_TIME->:"; SystemSetting[SETTINGS_AUTO_REBOOT_TIME			].nodePtr = (uint8_t*)"1440";                      	    //软件自动重启时间,默认一天重启一次,单位min，0：不重启
	SystemSettingName[SETTINGS_REBOOT			            ] = "SETTINGS_REBOOT----------->:"; SystemSetting[SETTINGS_REBOOT					].nodePtr = (uint8_t*)"1";                      	    //软件重启
	SystemSettingName[SETTINGS_WIFI_SSID		            ] = "SETTINGS_WIFI_SSID-------->:"; SystemSetting[SETTINGS_WIFI_SSID				].nodePtr = (uint8_t*)"WLAN";                      	    //WIFI名
	SystemSettingName[SETTINGS_WIFI_PASSWORD                ] = "SETTINGS_WIFI_PASSWORD---->:"; SystemSetting[SETTINGS_WIFI_PASSWORD			].nodePtr = (uint8_t*)"12345678";                      	//WIFI密码
	SystemSettingName[SETTINGS_CONNECT_MODE    	    		] = "SETTINGS_CONNECT_MODE----->:"; SystemSetting[SETTINGS_CONNECT_MODE    	        ].nodePtr = (uint8_t*)"1";                      	    //连接服务器模式 0:tcp 1:udp 2:coap 3:onenet
	SystemSettingName[SETTINGS_SERVER_IP                    ] = "SETTINGS_SERVER_IP-------->:"; SystemSetting[SETTINGS_SERVER_IP        		].nodePtr = (uint8_t*)"47.111.81.153";          	    //服务器IP地址 183.56.234.230 "47.111.81.153"
	SystemSettingName[SETTINGS_SERVER_PORT                  ] = "SETTINGS_SERVER_PORT------>:"; SystemSetting[SETTINGS_SERVER_PORT      		].nodePtr = (uint8_t*)"33333";                  	    //服务器端口
	SystemSettingName[SETTINGS_COAP_SERVER_IP               ] = "SETTINGS_COAP_SERVER_IP--->:"; SystemSetting[SETTINGS_COAP_SERVER_IP   		].nodePtr = (uint8_t*)"117.60.157.137";          	    //有人物联coap服务器IP地址
	SystemSettingName[SETTINGS_COAP_SERVER_PORT     		] = "SETTINGS_COAP_SERVER_PORT->:"; SystemSetting[SETTINGS_COAP_SERVER_PORT 		].nodePtr = (uint8_t*)"5683";                   	    //有人物联coap服务器端口
	SystemSettingName[SETTINGS_HEART_PERIOD             	] = "SETTINGS_HEART_PERIOD----->:"; SystemSetting[SETTINGS_HEART_PERIOD     		].nodePtr = (uint8_t*)"60";                      	    //心跳上传周期
	SystemSettingName[SETTINGS_PERIOD_UPLOAD1        		] = "SETTINGS_PERIOD_UPLOAD1--->:"; SystemSetting[SETTINGS_PERIOD_UPLOAD1   		].nodePtr = (uint8_t*)"60";                     	    //周期上传时间1单位s（秒）
	SystemSettingName[SETTINGS_PERIOD_UPLOAD2        		] = "SETTINGS_PERIOD_UPLOAD2--->:"; SystemSetting[SETTINGS_PERIOD_UPLOAD2   		].nodePtr = (uint8_t*)"60";                     	    //周期上传时间2单位s（秒）
	SystemSettingName[SETTINGS_ALARM_UPLOAD					] = "SETTINGS_ALARM_UPLOAD----->:"; SystemSetting[SETTINGS_ALARM_UPLOAD     		].nodePtr = (uint8_t*)"02:30:30";               	    //定时上传时间，使能、时、分、秒
	SystemSettingName[SETTINGS_WAKEUP_RUN_TIME     			] = "SETTINGS_WAKEUP_RUN_TIME-->:"; SystemSetting[SETTINGS_WAKEUP_RUN_TIME  	    ].nodePtr = (uint8_t*)"100000";                    	    //唤醒运行时间，单位ms（毫秒）
	SystemSettingName[SETTINGS_AREA_NUM                  	] = "SETTINGS_AREA_NUM--------->:"; SystemSetting[SETTINGS_AREA_NUM         		].nodePtr = (uint8_t*)"5000000000";             	    //区域编号
	SystemSettingName[SETTINGS_DEVICE_NUM               	] = "SETTINGS_DEVICE_NUM------->:"; SystemSetting[SETTINGS_DEVICE_NUM       		].nodePtr = (uint8_t*)"01234567";             	        //设备序号
	SystemSettingName[SETTINGS_OTA_IP                       ] = "SETTINGS_OTA_IP----------->:"; SystemSetting[SETTINGS_OTA_IP           		].nodePtr = (uint8_t*)"183.56.234.230";          	    //固件升级地址
	SystemSettingName[SETTINGS_OTA_PORT                   	] = "SETTINGS_OTA_PORT--------->:"; SystemSetting[SETTINGS_OTA_PORT         		].nodePtr = (uint8_t*)"8081";                   	    //固件升级端口
	SystemSettingName[SETTINGS_OTA_FLAG          			] = "SETTINGS_OTA_FLAG--------->:"; SystemSetting[SETTINGS_OTA_FLAG         		].nodePtr = (uint8_t*)"0";                      	    //升级标识
	SystemSettingName[SETTINGS_OTA_FILE_NAME     			] = "SETTINGS_OTA_FILE_NAME---->:"; SystemSetting[SETTINGS_OTA_FILE_NAME            ].nodePtr = (uint8_t*)"http://183.56.234.230:8081/DataGateway.bin";              //升级文件名
	SystemSettingName[SETTINGS_SALVE_DEVICE_TYPE 			] = "SETTINGS_SALVE_DEVICE_TYPE>:"; SystemSetting[SETTINGS_SALVE_DEVICE_TYPE		].nodePtr = (uint8_t*)"1";                    		    //被监控设备类型
	SystemSettingName[SETTINGS_METER_CNT1       			] = "SETTINGS_METER_CNT1------->:"; SystemSetting[SETTINGS_METER_CNT1	        	].nodePtr = (uint8_t*)"0";                    		    //水表计数1
	SystemSettingName[SETTINGS_METER_CNT2       			] = "SETTINGS_METER_CNT2------->:"; SystemSetting[SETTINGS_METER_CNT2	        	].nodePtr = (uint8_t*)"0";                    		    //水表计数2
	SystemSettingName[SETTINGS_LIMIT_CURRENT	 			] = "SETTINGS_LIMIT_CURRENT---->:"; SystemSetting[SETTINGS_LIMIT_CURRENT			].nodePtr = (uint8_t*)"999";                    	    //拉合闸限制电流
	SystemSettingName[SETTINGS_SWITCHOUT_PSW	 			] = "SETTINGS_SWITCHOUT_PSW---->:"; SystemSetting[SETTINGS_SWITCHOUT_PSW			].nodePtr = (uint8_t*)"000000";                    	    //拉合闸密码
	SystemSettingName[SETTINGS_AMMETER_NUM	     			] = "SETTINGS_AMMETER_NUM------>:"; SystemSetting[SETTINGS_AMMETER_NUM	            ].nodePtr = (uint8_t*)"1";                    		    //接入电表数目
	SystemSettingName[SETTINGS_AMMETER_INFO1     			] = "SETTINGS_AMMETER_INFO1---->:"; SystemSetting[SETTINGS_AMMETER_INFO1            ].nodePtr = (uint8_t*)"000000000001,100,000000000000";	//电表信息1[电表地址，限制电流（单位0.1A），拉闸密码]
	SystemSettingName[SETTINGS_AMMETER_INFO2	 			] = "SETTINGS_AMMETER_INFO2---->:"; SystemSetting[SETTINGS_AMMETER_INFO2			].nodePtr = (uint8_t*)"";                    		    //电表信息2
	SystemSettingName[SETTINGS_AMMETER_INFO3	 			] = "SETTINGS_AMMETER_INFO3---->:"; SystemSetting[SETTINGS_AMMETER_INFO3			].nodePtr = (uint8_t*)"";                    		    //电表信息3
	SystemSettingName[SETTINGS_AMMETER_INFO4	 			] = "SETTINGS_AMMETER_INFO4---->:"; SystemSetting[SETTINGS_AMMETER_INFO4			].nodePtr = (uint8_t*)"";                    		    //电表信息4
}

settings_ini si = {0};

uint8_t SystemSettingsBufTemp[SETTINGS_BUF_SIZE] = {0};

uint8_t System_SettingsSave(void)
{
	uint8_t ret = 0;
	uint32_t i = 0;
	uint32_t len = 0;
	uint16_t crc = 0;

	for(i = 0;i < SETTINGS_MAX_NUM;i++)
	{
		if(SystemSetting[i].len > SETTINGS_MAX_SIZE)
		{
			mprintf(LOG_INFO,"signal param len limit error:%d.\r\n",SystemSetting[i].len);
			SystemSetting[i].len = SETTINGS_MAX_SIZE;
		}
		SystemSettingsBufTemp[len++] = SystemSetting[i].len;
		memcpy(&SystemSettingsBufTemp[len],SystemSetting[i].nodePtr,SystemSetting[i].len);
		len = len + SystemSetting[i].len;
		/*结束符0x00*/
		SystemSettingsBufTemp[len] = 0;
		len++;
	}
	mprintf(LOG_INFO,"param total len:%d.\r\n",len);
	/*计算crc*/
	crc = Modbus_CRC16(SystemSettingsBufTemp,SETTINGS_BUF_SIZE - 2);
	if(len > (SETTINGS_BUF_SIZE-2))
	{
		mprintf(LOG_ERROR,"param len limit error:%d:%d.\r\n",SETTINGS_BUF_SIZE,len);
		ret = 1;
	}
	/*最后两个字节保存crc*/
	SystemSettingsBufTemp[SETTINGS_BUF_SIZE-2] = (crc >> 8);
	SystemSettingsBufTemp[SETTINGS_BUF_SIZE-1] = crc;
	if(si.storage_write(SETTINGS_START_ADDR,SystemSettingsBufTemp,SETTINGS_BUF_SIZE))
	{
		mprintf(LOG_ERROR,"write param error.\r\n");
		ret = 2;
	}
	memcpy(SystemSettingsBuf, SystemSettingsBufTemp, SETTINGS_BUF_SIZE);
	len = 0;
	for(i = 0;i < SETTINGS_MAX_NUM;i++)
	{
		SystemSetting[i].len = SystemSettingsBuf[len++];
		SystemSetting[i].nodePtr = &SystemSettingsBuf[len];
		len = len + SystemSetting[i].len + 1;
	}
	return ret;
}
/*
 * brief:恢复出厂设置
 */
uint8_t System_SettingsRestore(void)
{
	uint8_t ret = 0;
	uint32_t i = 0;
	uint32_t len = 0;
	uint16_t crc = 0;

	System_SettingsInitDefault();
	
	memset(SystemSettingsBuf, 0, SETTINGS_BUF_SIZE);
	
	for(i = 0;i < SETTINGS_MAX_NUM;i++)
	{
		SystemSetting[i].len = SystemSetting[i].nodePtr ? strlen((char*)SystemSetting[i].nodePtr) : 0;
		if(SystemSetting[i].len > SETTINGS_MAX_SIZE)
			SystemSetting[i].len = SETTINGS_MAX_SIZE;
		SystemSettingsBuf[len++] = SystemSetting[i].len;
		mprintf(LOG_INFO,"param %d len %d:%s.\r\n", i, SystemSetting[i].len, SystemSetting[i].len > 0 ? SystemSetting[i].nodePtr : "unkown.");
		strcpy(&SystemSettingsBuf[len], SystemSetting[i].nodePtr);
		/*每个参数以0x00结尾*/
		len = len + SystemSetting[i].len + 1;
	}
	mprintf(LOG_INFO,"param tottal len :%d.\r\n",len);
	/*计算crc*/
	crc = Modbus_CRC16(SystemSettingsBuf,SETTINGS_BUF_SIZE - 2);
	if(len > (SETTINGS_BUF_SIZE-2))
	{
		mprintf(LOG_ERROR,"param total length over limit:%d:%d.\r\n",SETTINGS_BUF_SIZE,len);
		ret = 1;
	}
	mprintf(LOG_INFO, "234");
	/*最后两个字节保存crc*/
	SystemSettingsBuf[SETTINGS_BUF_SIZE-2] = (crc >> 8);
	SystemSettingsBuf[SETTINGS_BUF_SIZE-1] = crc;
	if(si.storage_write(SETTINGS_START_ADDR,SystemSettingsBuf,SETTINGS_BUF_SIZE))
	{
		mprintf(LOG_ERROR,"write param error!\r\n");
		ret = 2;
	}
	mprintf(LOG_INFO, "123");
	return ret;
}


void System_SettingsInit(storage_wr_func rf, storage_wr_func wf)
{
	uint32_t i = 0;
	uint32_t len = 0;
	uint16_t crc = 0;
	//uint16_t pos = 0;
	
	si.ini_flag = 0;
	si.start_addr = SETTINGS_START_ADDR;
	si.stroage_size = SETTINGS_BUF_SIZE;
	si.storage_read = rf;
	si.storage_write = wf;

	System_SettingsInitDefault();

	// sys_settings_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "settings");

	// if(sys_settings_partition == NULL)
	// {
	// 	mprintf(LOG_ERROR,"no settings partition.\r\n");
	// 	return ;
	// }
	si.storage_read(SETTINGS_START_ADDR,SystemSettingsBuf,SETTINGS_BUF_SIZE);


	if(memcmp(&SystemSettingsBuf[1],SystemSetting[SETTINGS_SIGN_STRING].nodePtr,strlen((char*)SystemSetting[SETTINGS_SIGN_STRING].nodePtr)))
	{
		mprintf(LOG_INFO,"init param frist.\r\n");
		System_SettingsRestore();
	}
	else
	{
		i = 0;
		/*计算crc*/
		crc = Modbus_CRC16(SystemSettingsBuf,SETTINGS_BUF_SIZE - 2);
		while(crc != MG(SystemSettingsBuf[SETTINGS_BUF_SIZE-2],SystemSettingsBuf[SETTINGS_BUF_SIZE-1]))
		{
			i++;
			si.storage_read(SETTINGS_START_ADDR,SystemSettingsBuf,SETTINGS_BUF_SIZE);
			crc = Modbus_CRC16(SystemSettingsBuf,SETTINGS_BUF_SIZE - 2);
			if(i > 5)
			{
				mprintf(LOG_ERROR,"crc error,param restore:%04x : %04x.\r\n", crc, MG(SystemSettingsBuf[SETTINGS_BUF_SIZE-2],SystemSettingsBuf[SETTINGS_BUF_SIZE-1]));
				System_SettingsRestore();
				return;
			}
		}
		/*取出参数*/
		len = 0;
		for(i = 0;i < SETTINGS_MAX_NUM;i++)
		{
			SystemSetting[i].len = SystemSettingsBuf[len++];
			SystemSetting[i].nodePtr = &SystemSettingsBuf[len];
			len = len + SystemSetting[i].len + 1;
			mprintf(LOG_INFO,"%s%03d,len:%03d:%.*s\r\n",SystemSettingName[i] ? SystemSettingName[i] : "UNKOWN:",i,SystemSetting[i].len,SystemSetting[i].len,SystemSetting[i].nodePtr);
		}
		mprintf(LOG_INFO,"param total len:%d.\r\n",len);

	}
}

void System_SettingsReport(void)
{
	uint32_t i = 0, len = 0;
	for(i = 0;i < SETTINGS_MAX_NUM;i++)
	{
		len = len + SystemSetting[i].len;
		mprintf(LOG_IMP, "%s%03d,len:%03d:%.*s\r\n",SystemSettingName[i] ? SystemSettingName[i] : "UNKOWN:",i,SystemSetting[i].len,SystemSetting[i].len,SystemSetting[i].nodePtr);
	}
	mprintf(LOG_IMP, "param total len:%d.\r\n",len);
}
uint8_t System_SettingsSetSingle(uint8_t num,uint16_t len,uint8_t* data )
{
	if(num >= SETTINGS_MAX_NUM)
	{
		mprintf(LOG_ERROR,"param num error:%d.\r\n",num);
		return 1;
	}
	if(len > SETTINGS_MAX_SIZE)
	{
		mprintf(LOG_ERROR,"param len error:%d.\r\n",len);
		return 2;
	}
	if(data == NULL)
	{
		mprintf(LOG_ERROR,"param err.\r\n");
		return 3;
	}
	SystemSetting[num].len = len;
	SystemSetting[num].nodePtr = data;
	mprintf(LOG_INFO,"set param :%d:%.*s\r\n",num,len,data);
	return System_SettingsSave();
}
/*设置多个参数*/
/*格式-->参数号:参数长度:参数 .....*/
uint8_t System_SettingsSetMulti(uint8_t* data ,uint16_t num)
{
	uint32_t pos = 0;
	uint16_t i = 0;
	if(data == NULL)
	{
		mprintf(LOG_ERROR,"param error\r\n");
		return 1;
	}
	if(num == 0)
	{
		mprintf(LOG_ERROR,"no param need to be set\r\n");
		return 2;
	}
	for(i = 0;i < num;i++)
	{
		if(data[pos] >= SETTINGS_MAX_NUM)
		{
			mprintf(LOG_ERROR,"param num error:%d.\r\n",data[pos]);
			return 1;
		}
		if(data[pos+1] > SETTINGS_MAX_SIZE)
		{
			mprintf(LOG_ERROR,"param len error:%d.\r\n",data[pos+1]);
			return 2;
		}
		SystemSetting[data[pos]].len = data[pos+1];
		SystemSetting[data[pos]].nodePtr = &data[pos+2];
		mprintf(LOG_INFO,"set param:%d:%.*s\r\n",data[pos],data[pos+1],&data[pos+2]);
		pos = pos + data[pos+1] + 2;
	}
	return System_SettingsSave();
}



